//
//  UIButton+KYExtension.swift
//  KFManager
//
//  Created by kingly on 2016/11/15.
//  Copyright © 2016年 kingly inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. All rights reserved.
//

import UIKit

extension UIButton {


    /// 创建带背景的图像按钮
    ///
    /// - Parameters:
    ///   - imageName: 按钮图案
    ///   - backgroundImageName: 背景名称
    /// - Returns: 返回创建带背景的图像按钮
    func  ky_buttonWithBackgroundimage (imageName : String?,backgroundImageName: String?) -> UIButton {

        let button:UIButton = UIButton(type:.custom)

        button.setImage(UIImage(named: imageName!),for: .normal)  //设置图标
        button.adjustsImageWhenHighlighted = true
        button.adjustsImageWhenDisabled = true

        button.setBackgroundImage(UIImage(named: backgroundImageName!), for: .normal)

        return button;

    }
    
    /// 创建带背景的图像按钮
    ///
    /// - Parameter imageName: 按钮图案
    /// - Returns: 返回创建带背景的图像按钮
    func ky_custombutton(imageName : String) -> UIButton {
    
      let button = UIButton.init(type:UIButton.ButtonType.custom)
     
        button.setImage(UIImage(named: imageName),for: .normal)  //设置图标
        button.adjustsImageWhenHighlighted = true
        button.adjustsImageWhenDisabled = true
      
        return button;
    }
    
    /// 此方法设置图像和标题为UIButton
    /// 复位titleposition相对于按钮图像。
    /// 添加additionalspacing按钮图片和标题之间的要求
    /// titleposition功能方面，只uiviewcontentmodetop，uiviewcontentmodebottom，uiviewcontentmodeleft和UIViewContentModeRight
    ///
    /// - Parameters:
    ///   - anImage: image 
    ///   - highlightedImage: 高亮 image 
    ///   - title: button的titleLabel
    ///   - titlePosition: titleLabel的方向 默认在UIbutton的中间
    ///   - additionalSpacing: UIButton和title的空隙
    ///   - state: UIControlState
    /// - Returns: 返回一个自定义UIButton
  @objc func ky_positionLabel(image anImage: UIImage?, highlightedImage: UIImage?,title: NSString!, titlePosition: UIView.ContentMode, additionalSpacing: CGFloat, state: UIControl.State)  -> UIButton  {
    
    let button = UIButton.init(type:UIButton.ButtonType.custom)

        button.imageView?.contentMode = .center
        button.setImage(anImage,for: .normal)  //设置图标
        button.setImage(highlightedImage,for: .highlighted)  //高亮图标
    
        button.titleLabel?.contentMode = .center
        button.setTitle(title as String?, for: state)
        let imageSize = button.imageRect(forContentRect: self.frame)
        let titleFont = button.titleLabel?.font!
    let titleSize = title.size(withAttributes: [kCTFontAttributeName as NSAttributedString.Key: titleFont!])
        
        var titleInsets: UIEdgeInsets
        var imageInsets: UIEdgeInsets
        
        switch (titlePosition){
        case .top:
            titleInsets = UIEdgeInsets(top: -(imageSize.height + titleSize.height + additionalSpacing), left: -(imageSize.width), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -titleSize.width)
        case .bottom:
            titleInsets = UIEdgeInsets(top: (imageSize.height + titleSize.height + additionalSpacing), left: -(imageSize.width), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -titleSize.width)
        case .left:
            titleInsets = UIEdgeInsets(top: 0, left: -(imageSize.width * 2), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -(titleSize.width * 2 + additionalSpacing))
        case .right:
            titleInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -additionalSpacing)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        default:
            titleInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        }
        
        button.titleEdgeInsets = titleInsets
        button.imageEdgeInsets = imageInsets
     
       return button;
    }
    
    
  @objc func set(image anImage: UIImage?, title: NSString!, titlePosition: UIView.ContentMode, additionalSpacing: CGFloat, state: UIControl.State){
        self.imageView?.contentMode = .center
        self.setImage(anImage, for: state)
        
        positionLabelRespectToImage(title: title!, position: titlePosition, spacing: additionalSpacing)
        
        self.titleLabel?.contentMode = .center
        self.setTitle(title as String?, for: state)
    }

    
  private func positionLabelRespectToImage(title: NSString, position: UIView.ContentMode, spacing: CGFloat) {
        let imageSize = self.imageRect(forContentRect: self.frame)
        let titleFont = self.titleLabel?.font!
    let titleSize = title.size(withAttributes: [kCTFontAttributeName as NSAttributedString.Key: titleFont!])
        
        var titleInsets: UIEdgeInsets
        var imageInsets: UIEdgeInsets
        
        switch (position){
        case .top:
            titleInsets = UIEdgeInsets(top: -(imageSize.height + titleSize.height + spacing), left: -(imageSize.width), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -titleSize.width)
        case .bottom:
            titleInsets = UIEdgeInsets(top: (imageSize.height + titleSize.height + spacing), left: -(imageSize.width), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -titleSize.width)
        case .left:
            titleInsets = UIEdgeInsets(top: 0, left: -(imageSize.width * 2), bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -(titleSize.width * 2 + spacing))
        case .right:
            titleInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -spacing)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        default:
            titleInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        }
        
        self.titleEdgeInsets = titleInsets
        self.imageEdgeInsets = imageInsets
    }
}


extension UIButton{
    
    // 改进写法【推荐】
    private struct RuntimeKey {
        static let clickEdgeInsets = UnsafeRawPointer.init(bitPattern: "clickEdgeInsets".hashValue)
        /// ...其他Key声明
    }
    /// 需要扩充的点击边距
    public var hw_clickEdgeInsets: UIEdgeInsets? {
        set {
            objc_setAssociatedObject(self, UIButton.RuntimeKey.clickEdgeInsets!, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY)
        }
        get {
            return objc_getAssociatedObject(self, UIButton.RuntimeKey.clickEdgeInsets!) as? UIEdgeInsets ?? UIEdgeInsets.zero
        }
    }
    // 重写系统方法修改点击区域
    open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        super.point(inside: point, with: event)
        var bounds = self.bounds
        if (hw_clickEdgeInsets != nil) {
            let x: CGFloat = -(hw_clickEdgeInsets?.left ?? 0)
            let y: CGFloat = -(hw_clickEdgeInsets?.top ?? 0)
            let width: CGFloat = bounds.width + (hw_clickEdgeInsets?.left ?? 0) + (hw_clickEdgeInsets?.right ?? 0)
            let height: CGFloat = bounds.height + (hw_clickEdgeInsets?.top ?? 0) + (hw_clickEdgeInsets?.bottom ?? 0)
            bounds = CGRect(x: x, y: y, width: width, height: height) //负值是方法响应范围
        }
        return bounds.contains(point)
    }
}
